package com.hawthorn.admin.service.appuser.impl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hawthorn.admin.constant.DicConstants;
import com.hawthorn.admin.feign.CloudStoreFeignService;
import com.hawthorn.admin.model.po.AppMenuPO;
import com.hawthorn.admin.model.po.AppUserMenuMapPO;
import com.hawthorn.admin.model.po.AppUserPO;
import com.hawthorn.admin.repository.AppMenuMapper;
import com.hawthorn.admin.repository.AppUserMapper;
import com.hawthorn.admin.repository.AppUserMenuMapMapper;
import com.hawthorn.admin.repository.SysDeptMapper;
import com.hawthorn.admin.service.appuser.AppUserService;
import com.hawthorn.component.constant.FormatConstant;
import com.hawthorn.component.utils.bean.Map2ObjUtil;
import com.hawthorn.platform.exception.BizCode;
import com.hawthorn.platform.service.ExcelApiService;
import com.hawthorn.platform.service.TransResultService;
import com.hawthorn.platform.utils.common.ArrayMyUtil;
import com.hawthorn.platform.utils.common.MyUtil;
import com.hawthorn.platform.utils.iassert.AssertMyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>todo app用户service</p>
 * @author: sunwanzhong
–
 * @created: 2023/2/14 21:47
 * @version v1.0.1
 * @copyright: Copyright (c) 2023 sunwanzhong
 */
@Service
@Slf4j
public class AppUserServiceImpl implements AppUserService
{

  @Resource
  private AppUserMapper appUserMapper;

  @Resource
  private AppMenuMapper appMenuMapper;

  @Resource
  private AppUserMenuMapMapper appUserMenuMapMapper;

  @Resource
  private TransResultService transResultService;

  @Resource
  private ExcelApiService excelApiService;

  @Resource
  private CloudStoreFeignService cloudStoreFeignService;

  @Resource
  private SysDeptMapper sysDeptMapper;

  /**
   * <p>todo 插入app用户表</p>
   * @param:
   * @return: java.util.Map<java.lang.String, java.lang.Object>
   * @author: sunwanzhong
   * @date: 2023/2/14 21:49
   * @version: 1.0.1
   * Modification History:
   * Date       Author       Version       Description
   * -----------------------------------------------------------
   * 2023/2/14     sunwanzhong     v1.0.1        init
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public Map<String, Object> saveAppUser(Map<String, Object> param)
  {
    while (param.values().remove(null)) ;
    AppUserPO appUserPO = Map2ObjUtil.toObject(param, AppUserPO.class);
    AssertMyUtil.notNull(appUserPO, BizCode.VARIABLE_NOT_NULL, "appUserPO");
    //目前暂定通过手机号校验唯一
    LambdaQueryWrapper<AppUserPO> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(AppUserPO::getPhone, appUserPO.getPhone());
    queryWrapper.ne(AppUserPO::getBizType, 102402);
    List<AppUserPO> appUserList = appUserMapper.selectList(queryWrapper);
    if (appUserList.size() > 0)
    {
      AssertMyUtil.errMsg(BizCode.USER_ALREADY_REG);
    }
    appUserMapper.save(appUserPO);
    //同步创建app_user_menu_map表信息
    // setRole(appUserPO.getPhone());  //讨论决定主账号默认全部权限，不需要插入
    return appUserPO.toMaps();
  }

  /**
   * <p>todo app用户授权</p>
   * @author: sunwanzhong
   * @date: 2023/2/14 22:54
   * @version: 1.0.1
   */
  private void setRole(String phone)
  {
    LambdaQueryWrapper<AppMenuPO> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(AppMenuPO::getStatus, "100201");
    List<AppMenuPO> appMenuList = appMenuMapper.selectList(queryWrapper);
    //插入app_user_menu_map
    List<AppUserMenuMapPO> list = new ArrayList<>();
    if (appMenuList.size() > 0)
    {
      for (AppMenuPO appMenu : appMenuList)
      {
        AppUserMenuMapPO appUserMenuMap = new AppUserMenuMapPO();
        appUserMenuMap.setMenuId(appMenu.getId());
        appUserMenuMap.setMenuCode(appMenu.getCode());
        appUserMenuMap.setMenuName(appMenu.getTitle());
        appUserMenuMap.setUserAccount(phone);
        appUserMenuMap.setBizType(Integer.parseInt(DicConstants.APPYHYWLX_02));
        list.add(appUserMenuMap);
      }
      appUserMenuMapMapper.saveBatch(list, AppUserMenuMapPO.class);
    }
  }

  /**
   * <p>todo 修改app用户手机号</p>
   * @author: sunwanzhong
  –
   * @created: 2023/3/6 19:40
   * @version v1.0.1
   * @copyright: Copyright (c) 2023 sunwanzhong
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public Map<String, Object> updateAppUserPhone(Map<String, Object> param)
  {
    String oldPhone = (String) param.get("oldPhone");
    String newPhone = (String) param.get("newPhone");
    //更新app用户表手机号
    QueryWrapper<AppUserPO> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("phone", oldPhone);
    queryWrapper.eq("biz_type", 102402);
    AppUserPO appUser = appUserMapper.selectOne(queryWrapper);
    appUser.setPhone(newPhone);
    appUserMapper.updateById(appUser);
    //同步更新app_user_menu_map表user_account信息
    LambdaQueryWrapper<AppUserMenuMapPO> qwList = new LambdaQueryWrapper<>();
    qwList.eq(AppUserMenuMapPO::getUserAccount, oldPhone);
    List<AppUserMenuMapPO> appUserMenuMapPOList = appUserMenuMapMapper.selectList(qwList);
    if (!StringUtils.isEmpty(appUserMenuMapPOList) && appUserMenuMapPOList.size() > 0)
    {
      for (AppUserMenuMapPO entity : appUserMenuMapPOList)
      {
        entity.setUserAccount(newPhone);
      }
      appUserMenuMapMapper.updateBatch(appUserMenuMapPOList, AppUserMenuMapPO.class);
    }
    return appUser.toMaps();
  }

  @Override
  public void updateAppUserInfo(Map<String, Object> param)
  {
    AppUserPO appUserPO = Map2ObjUtil.toObject(param, AppUserPO.class);
    QueryWrapper<AppUserPO> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("phone", appUserPO.getPhone());
    queryWrapper.eq("biz_type", 102402);
    AppUserPO appUser = appUserMapper.selectOne(queryWrapper);
    String phone = param.get("phone").toString();
    String deptId = param.get("deptId").toString();
    String oemCompanyId = param.get("oemCompanyId").toString();
    appUser.setPhone(phone);
    appUser.setDeptId(Long.parseLong(deptId));
    if (!StringUtils.isEmpty(param.get("companyId")))
    {
      String companyId = param.get("companyId").toString();
      appUser.setCompanyId(Long.parseLong(companyId));
    }
    appUser.setOemCompanyId(Long.parseLong(oemCompanyId));
    appUserMapper.updateById(appUser);
  }

  @Override
  public void delAppUser(String id)
  {
    AppUserPO appUser = appUserMapper.selectById(id);
    if (!"102402".equals(appUser.getBizType()))
    {
      AssertMyUtil.errMsg("只可以删除麒麟云店账号");
    }
    if (StringUtils.isEmpty(appUser.getDeptId()))
    {
      //app用户查询这个功能，在删除用户的时候，如果被删除的用户，dept_id为空，则需要，通过手机号，
      // 去CPS库中的以link_phone查询cms_cloud_store表中对应记录的store_code是否为空，如果为空则将这条记录删除掉。否则不能删除。
      Map<String, Object> map = new HashMap<>();
      map.put("linkPhone", appUser.getPhone());
      Map<String, Object> storeStatusMap = cloudStoreFeignService.findStoreStatus(map);
      JSONObject jsonStoreStatusMap = JSONUtil.parseObj(storeStatusMap);
      String jsonStatus = jsonStoreStatusMap.get("status").toString();
      if ("fail".equals(jsonStatus))
      {
        AssertMyUtil.errMsg(jsonStoreStatusMap.get("message").toString());
      } else if ("ok".equals(jsonStatus))
      {
        appUserMapper.deleteById(id);
      }
    } else
    {
      // 要用dept_id去cps库中的cms_cloud_store表中查询门店状态in(301401,301402)可以删除。其他状态都不可以删除。
      //调用Feign接口判断是否存在门店状态
      Map<String, Object> map = new HashMap<>();
      map.put("deptId", appUser.getDeptId());
      Map<String, Object> storeStatusMap = cloudStoreFeignService.findStoreStatus(map);
      JSONObject jsonStoreStatusMap = JSONUtil.parseObj(storeStatusMap);
      String jsonStatus = jsonStoreStatusMap.get("status").toString();
      if ("fail".equals(jsonStatus))
      {
        AssertMyUtil.errMsg(jsonStoreStatusMap.get("message").toString());
      }
      if (!StringUtils.isEmpty(jsonStoreStatusMap.get("datas")))
      {
        Map<String, Object> jsonMap = (Map<String, Object>) jsonStoreStatusMap.get("datas");
        String storeStatus = MyUtil.getValue(jsonMap.get("storeStatus"));
        if ("301401".equals(storeStatus) || "301402".equals(storeStatus))
        {
          // 删除门店
          Map<String, Object> delMap = cloudStoreFeignService.delStore(map);
          JSONObject jsonDelMap = JSONUtil.parseObj(delMap);
          String status = jsonStoreStatusMap.get("status").toString();
          if ("fail".equals(status))
          {
            AssertMyUtil.errMsg(jsonDelMap.get("message").toString());
          }
          // 删除APPuser
          appUserMapper.deleteById(id);
          // 删除部门
          sysDeptMapper.deleteById(appUser.getDeptId());
          // 删除菜单
          if (!StringUtils.isEmpty(appUser.getPhone()))
          {
            LambdaUpdateWrapper<AppUserMenuMapPO> updateWrapper = new LambdaUpdateWrapper();
            updateWrapper.eq(AppUserMenuMapPO::getUserAccount, appUser.getPhone());
            appUserMenuMapMapper.delete(updateWrapper);
          }
        } else
        {
          AssertMyUtil.errMsg("此账号门店已经认证或处于公共资源库不可删除");
        }
      }
    }
  }

  @Override
  public Map<String, Object> findIsExist(Map<String, Object> param)
  {
    Map<String, Object> map = new HashMap<>();
    String newPhone = (String) param.get("newPhone");
    //更新app用户表手机号
    QueryWrapper<AppUserPO> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("phone", newPhone);
    queryWrapper.eq("biz_type", 102402);
    int count = appUserMapper.selectCount(queryWrapper);
    if (count > 0)
    {
      map.put("info", "false");
    }
    return map;
  }

  /**
   * <p> todo app用户查询-查询列表
   * @param:
   * @param: null
   * @return: {@link null}
   * @author: yumiaoting <br>
   * @date: 2023/2/21 10:30 <br>
   * @version: 1.0.1
   * Modification History:
   * Date   Author   Version   Description
   * -----------------------------------------------------------
   * 2023/2/21   yumiaoting   1.0.1
   */
  public IPage<Map<String, Object>> findAppUser(Page<Map<String, Object>> page, String conditions)
  {
    return transResultService.transResult(appUserMapper.findAppUser(page, conditions), this.getTransDic());
  }

  /**
   * <p> todo 导出方法
   * @param:
   * @param: null
   * @return: {@link null}
   * @author: yumiaoting <br>
   * @date: 2023/2/21 11:49 <br>
   * @version: 1.0.1
   * Modification History:
   * Date   Author   Version   Description
   * -----------------------------------------------------------
   * 2023/2/21   yumiaoting   1.0.1
   */
  public void exportAppUser(HttpServletResponse response, String fileName, Map<String, Object> params)
  {
    String header = MyUtil.getValue(params.get("header"));
    String param = MyUtil.getValue(params.get("params"));
    String qc = MyUtil.getConditionsWhere(param, null);
    List<List<String>> headList = new ArrayList<>();
    List<String> headFields = excelApiService.toHeader(header, headList);
    String fields = ArrayMyUtil.join(headFields.toArray(), ",");
    List<Map<String, Object>> dataList = appUserMapper.exportAppUser(fields, qc);
    excelApiService.export(response, fileName, headFields, headList, dataList, this.getTransDic());
  }

  private HashMap<String, String> getTransDic()
  {
    HashMap<String, String> transHash = new HashMap<>();
    transHash.put("createBy", "user|name");
    transHash.put("checkBy", "user|name");
    transHash.put("createTime", "date|" + FormatConstant.SIMPLE_DATE_TIME_FORMAT);
    transHash.put("checkTime", "date|" + FormatConstant.SIMPLE_DATE_TIME_FORMAT);
    transHash.put("userKind", "dic|" + DicConstants.APPYHLB);
    transHash.put("loginPlatform", "dic|" + DicConstants.APPDLPT);
    transHash.put("loginMode", "dic|" + DicConstants.JFDDZFFS);
    transHash.put("bizType", "dic|" + DicConstants.APPYHYWLX);
    transHash.put("status", "dic|" + DicConstants.YXZT);
    return transHash;
  }
}
